package com.lpwa.system.service.impl;

import java.io.IOException;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Future;

import com.lpwa.common.config.Global;
import com.lpwa.common.config.datasource.DynamicDataSourceContextHolder;
import com.lpwa.common.core.page.PageDomain;
import com.lpwa.common.core.page.TableSupport;
import com.lpwa.common.enums.DataSourceType;
import com.lpwa.common.utils.*;
import com.lpwa.common.utils.http.HttpUtils;
import com.lpwa.system.domain.*;
import com.lpwa.system.domain.tagdata.info.TagInfo;
import com.lpwa.system.domain.tagdata.info.TagTow;
import com.lpwa.system.domain.tagdata.position.TagOne;
import com.lpwa.system.domain.tagdata.position.TagPositiont;
import com.lpwa.system.domain.tagdata.position.Zone;
import com.lpwa.system.domain.tagdata.specific.DeveloperSpecificData;
import com.lpwa.system.domain.tagdata.specific.SpecificData;
import com.lpwa.system.domain.tagdata.specific.TagThree;
import com.lpwa.system.domain.tagdata.tdgs.TdgsTag;
import com.lpwa.system.domain.tagdata.tdgs.TdgsTagPositiont;
import com.lpwa.system.mapper.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import com.lpwa.system.service.ITagDataService;
import com.lpwa.common.core.text.Convert;
import com.alibaba.fastjson.JSON;

import javax.annotation.Resource;

/**
 * 标签数据 服务层实现
 *
 * @author tanmu
 * @date 2019-06-20
 */
@Service
public class TagDataServiceImpl implements ITagDataService
{
	@Autowired
	private TagDataMapper tagDataMapper;
	@Autowired
	private LablePersonMapper lablePersonMapper;
	@Autowired
	private LableMapper lableMapper;
	@Autowired
	private TagAlarmDataMapper tagAlarmDataMapper;
	@Autowired
	private PersonMapper personMapper;
	@Autowired
	private RedisUtil redisUtil;
//	@Autowired
//	private WebSocketServer webSocketServer;
	@Autowired
	private AreaMapper areaMapper;
	@Resource(name = "myDataThreadPool")
	private ExecutorService threadPool;
	/**
     * 查询标签数据信息
     *
     * @param id 标签数据ID
     * @return 标签数据信息
     */
    @Override
	public TagData selectTagDataById(Long id)
	{
	    return tagDataMapper.selectTagDataById(id);
	}

	@Override
//	@DataSource(value = DataSourceType.SLAVE)
	public List<TagData> selectTagDataList(TagData tagData) {
		List<TagData> tagDataList = tagDataMapper.selectTagDataListByTableName(tagData);
		return tagDataList;
	}

	/**
     * 查询标签数据列表(无查询条件查询)
     *
     * @param tagData 标签数据信息
     * @return 标签数据集合
     */
	@Override
	public List<TagData> selectTagDataList(TagData tagData,List<Tag> tagList)
	{
		//通过标签表查询所有标签，然后根据每一个标签Id对应一张分表的关系进行union查询
		//查询所有标签
		PageDomain pageDomain = TableSupport.buildPageRequest();
		Integer pageNum = pageDomain.getPageNum();
		Integer pageSize = pageDomain.getPageSize();
		tagData.setStart((pageNum-1)*pageSize);
		tagData.setEnd(pageSize);
		StringBuilder sql = new StringBuilder();
		sql.append("select a.* from (");
		String where = getWhere(tagData);
		//分页
		for (int i=0;i<tagList.size();i++){
			if (i==(tagList.size()-1)){
				sql.append(" (select * from tag_data_"+tagList.get(i).getTagId());
				sql.append(" where 1=1" + where);
//				sql.append(" limit " + (pageNum-1)*pageSize+","+pageSize);
				sql.append(")");
			}else {
				sql.append(" (select * from tag_data_"+tagList.get(i).getTagId());
				sql.append(" where 1=1" + where);
//				sql.append(" limit " + (pageNum-1)*pageSize+","+pageSize);
				sql.append(" )union all");
			}
		}
		sql.append(") as a ");
		if (!StringUtils.isEmpty(sql)){
			tagData.setSql(sql.toString());
			return tagDataMapper.selectTagDataList(tagData);
		}
		return null;
	}
	/**
	 * 查询标签数据列表（有查询条件，查询条件部位包含tagID）
	 *
	 * @param tagData 标签数据信息
	 * @return 标签数据集合
	 */
	@Override
	public List<TagData> selectTagDataListCondition(TagData tagData,List<Tag> tagList)
	{
		//通过标签表查询所有标签，然后根据每一个标签Id对应一张分表的关系进行union查询
		//查询所有标签
		StringBuilder sql = new StringBuilder();
		sql.append("select a.* from (");
		String where = getWhere(tagData);
		//分页
		for (int i=0;i<tagList.size();i++){
			if (i==(tagList.size()-1)){
				sql.append(" (select * from tag_data_"+tagList.get(i).getTagId());
				sql.append(" where 1=1" + where);
//				sql.append(" limit " + (pageNum-1)*pageSize+","+pageSize);
				sql.append(")");
			}else {
				sql.append(" (select * from tag_data_"+tagList.get(i).getTagId());
				sql.append(" where 1=1" + where);
//				sql.append(" limit " + (pageNum-1)*pageSize+","+pageSize);
				sql.append(" )union all");
			}
		}
		sql.append(") as a ");
		if (!StringUtils.isEmpty(sql)){
			tagData.setSql(sql.toString());
			return tagDataMapper.selectTagDataListCondition(tagData);
		}
		return null;
	}
	/**
	 * 查询标签数据列表（查询条件包含tagID）
	 *
	 * @param tagData 标签数据信息
	 * @return 标签数据集合
	 */
	@Override
	public List<TagData> selectTagDataListByTableName(TagData tagData)
	{
//		//查询标签Id对应的分表，进行分页查询
//		tagData.setTableName("tag_data_"+tagData.getTagId());
		//查询所有表名
		DynamicDataSourceContextHolder.setDataSourceType(DataSourceType.SLAVE.name());
		List<TagData> tagDataList = tagDataMapper.selectTagDataListByTableName(tagData);
		DynamicDataSourceContextHolder.clearDataSourceType();
		return tagDataList;
	}
	/**
	 * 查询标签数据列表（有查询条件，查询条件部位包含tagID）
	 * @return 标签数据集合
	 */
	@Override
	public Integer getCount()
	{
		TagData tagData = new TagData();
		List<Tag> tagList = lableMapper.selectLableList(new Tag());
		List<TagData> list = new ArrayList<TagData>();
		if (tagList.size()>0){
			//通过标签表查询所有标签，然后根据每一个标签Id对应一张分表的关系进行union查询
			//查询所有标签
			StringBuilder sql = new StringBuilder();
			sql.append("select count(0) from (");
			String where = getWhere(tagData);
			//分页
			for (int i=0;i<tagList.size();i++){
				if (i==(tagList.size()-1)){
					sql.append(" (select * from tag_data_"+tagList.get(i).getTagId());
					sql.append(" where 1=1" + where);
//				sql.append(" limit " + (pageNum-1)*pageSize+","+pageSize);
					sql.append(")");
				}else {
					sql.append(" (select * from tag_data_"+tagList.get(i).getTagId());
					sql.append(" where 1=1" + where);
//				sql.append(" limit " + (pageNum-1)*pageSize+","+pageSize);
					sql.append(" )union all");
				}
			}
			sql.append(") as a ");
			if (!StringUtils.isEmpty(sql)){
				tagData.setSql(sql.toString());
				return tagDataMapper.getCount(tagData);
			}
		}

		return null;
	}
	/**
	 * 导出数据查询
	 *
	 * @param tagData 标签数据信息
	 * @return 标签数据集合
	 */
	@Override
	public List<TagData> excelTagDataList(TagData tagData)
	{
		if (!StringUtils.isEmpty(tagData.getTagId())){
			//查询标签Id对应的分表，进行分页查询
			tagData.setTableName("tag_data_"+tagData.getTagId());
			return tagDataMapper.selectTagDataListByTableName(tagData);
		}
//		else if (!StringUtils.isEmpty(tagData.getPersonId())){
//			//人员ID不为空,查询人员对应的标签ID
//			String tagId = selectbindLableId(tagData.getPersonId());
//			tagData.setTableName("tag_data_"+tagData.getTagId());
//			return tagDataMapper.selectTagDataListByTableName(tagData);
//		}
		else{
			//通过标签表查询所有标签，然后根据每一个标签Id对应一张分表的关系进行union查询
			//查询所有标签
			String where = getWhere(tagData);
			List<Tag> tagList = lableMapper.selectLableList(new Tag());
			StringBuilder sql = new StringBuilder();
			if (tagList.size()>0){
				sql.append("select a.* from (");
				for (int i=0;i<tagList.size();i++){
					if (i==(tagList.size()-1)){
						sql.append(" select * from tag_data_"+tagList.get(i).getTagId());
						sql.append(" where 1=1" + where);
					}else {
						sql.append(" select * from tag_data_"+tagList.get(i).getTagId());
						sql.append(" where 1=1" + where);
						sql.append(" union all");
					}
				}
				sql.append(") as a ");
			}
			if (!StringUtils.isEmpty(sql)){
				tagData.setSql(sql.toString());
				return tagDataMapper.selectTagDataList(tagData);
			}
			return null;
		}
	}
	public String getWhere(TagData tagData){
		String where = "";
		//基站ID
		if (StringUtils.isNotEmpty(tagData.getRssiLocator())){
			where+= " and rssiLocator='"+tagData.getRssiLocator()+"'";
		}
		if (StringUtils.isNotEmpty(tagData.getStatus())){
			where+= " and status='"+tagData.getStatus()+"'";
		}
		if (StringUtils.isNotEmpty(tagData.getSensorType())){
			where+= " and sensorType='"+tagData.getSensorType()+"'";
		}
		if (StringUtils.isNotEmpty(tagData.getPersonId())){
			where+= " and person_id='"+tagData.getPersonId()+"'";
		}
//		if (!StringUtils.isNull(tagData.getCreateTime())){
//			where+= " and sensorType="+tagData.getSensorType();
//		}

		return where;
	}
	/**
	 * 根据人员Id查询已绑定标签Id
	 *
	 * @String personId 人员信息
	 * @return 结果
	 */
	public String selectbindLableId(String personId) {
		TagPerson lablePerson = new TagPerson();
		lablePerson.setPersonId(personId);
		lablePerson.setIsBind("1");
		//查询绑定标签Id
		List<TagPerson> lablePeopleList=lablePersonMapper.selectLablePersonList(lablePerson);
		if (lablePeopleList.size()>0){
			return lablePeopleList.get(0).getTagId();
		}else {
			return null;
		}
	}
    /**
     * 新增标签数据
     *
     * @param tagData 标签数据信息
     * @return 结果
     */
	@Override
	public int insertTagData(TagData tagData)
	{
	    return tagDataMapper.insertTagData(tagData);
	}

	/**
     * 修改标签数据
     *
     * @param tagData 标签数据信息
     * @return 结果
     */
	@Override
	public int updateTagData(TagData tagData)
	{
	    return tagDataMapper.updateTagData(tagData);
	}

	/**
     * 删除标签数据对象
     *
     * @param ids 需要删除的数据ID
     * @return 结果
     */
	@Override
	public int deleteTagDataByIds(String ids)
	{
		return tagDataMapper.deleteTagDataByIds(Convert.toStrArray(ids));
	}
	/**
	 * 通过TDMP-le接口获取标签数据信息并做相关处理
	 * @return 结果
	 */
	@Override
	public void getTagData() {
		String httpAddress = Global.getTdmpLeIpAndPort();
		String tagPosition = HttpUtils.sendPost(" http://"+httpAddress+"/qpe/getTagPosition","version=2");
		TagPositiont tagPos = JSON.parseObject(tagPosition, TagPositiont.class);
		String tagInfo = HttpUtils.sendPost(" http://"+httpAddress+"/qpe/getTagInfo","version=2&humanReadable=true&maxAge=10000");
		TagInfo info = JSON.parseObject(tagInfo, TagInfo.class);
		String specificData = HttpUtils.sendPost(" http://"+httpAddress+"/qpe/getDeveloperSpecificData","humanReadable=true");
		SpecificData specific = JSON.parseObject(specificData, SpecificData.class);
		List<TagOne> oneList = new ArrayList<TagOne>();
		List<TagTow> tagTows =new ArrayList<TagTow>();
		if (info.getTags()!=null&&info.getTags().size()>0){
			tagTows = info.getTags();
		}
		List<TagThree> tagThrees =new ArrayList<TagThree>();
		if (specific.getTags()!=null&&specific.getTags().size()>0){
			tagThrees = specific.getTags();
		}
		if (!StringUtils.isNull(tagPos.getTags())){
			for (TagOne tagOne:tagPos.getTags()){
				String tagOneId = tagOne.getId();
				if (checkIsExistTag(tagOneId)){//校验标签是否存在，不存在的标签数据剔除掉不做处理

					TagData tagData = new TagData();
					//生成ID
					Long id = IdUtil.nextId();
					tagData.setId(id);
					tagData.setTagId(tagOneId);
					//获取坐标信息时间
					Long positionTS = tagOne.getPositionTS();
					if (!StringUtils.isNull(positionTS)){
						String positionTime = DateUtils.stampToDate(positionTS.toString());
						tagData.setPositionTS(DateUtils.parseDate(positionTime));
					}
					//获取坐标xyz
					List<BigDecimal> positions =tagOne.getPosition();
					tagData.setX(positions.get(0));
					tagData.setY(positions.get(1));
					tagData.setZ(positions.get(2));
					TagTow tagTow = new TagTow();
					if (tagTows.size()>0){
						for (TagTow t:tagTows){
							if (t.getId().equals(tagOneId)){
								tagTow = t;
								tagTows.remove(t);
								break;
							}
						}
						//获取数据产生时间
						Long lastPacketTS = tagTow.getLastPacketTS();
						if (!StringUtils.isNull(lastPacketTS)){
							String lastPacketTime = DateUtils.stampToDate(lastPacketTS.toString());
							tagData.setLastPacketTS(DateUtils.parseDate(lastPacketTime));
						}
						//获取电量信息
						BigDecimal batteryVoltage = tagTow.getBatteryVoltage();
						Long batteryVoltageTS = tagTow.getBatteryVoltageTS();
						if (!StringUtils.isNull(batteryVoltageTS)){
							String batteryVoltageTime = DateUtils.stampToDate(batteryVoltageTS.toString());
							tagData.setBatteryVoltageTS(DateUtils.parseDate(batteryVoltageTime));
						}
						//获取信号强度
						int rssi = tagTow.getRssi();
						tagData.setRssi(rssi);
						//获取rssiLocator基站ID
						String rssiLocator = tagTow.getRssiLocator();
						tagData.setRssiLocator(rssiLocator);
					}
					TagThree tagThree = new TagThree();
					if (tagThrees.size()>0) {
						for (TagThree t : tagThrees) {
							if (t.getId().equals(tagOneId)) {
								tagThree = t;
								tagThrees.remove(t);
								break;
							}
						}
					}
					List<DeveloperSpecificData> developerSpecificDataList = new ArrayList<DeveloperSpecificData>();
					developerSpecificDataList = tagThree.getDeveloperSpecificData();
					Long maxdataTS=null;
					String data = null;
					if ((!StringUtils.isEmpty(developerSpecificDataList))&&developerSpecificDataList.size()>0){
						for (DeveloperSpecificData developerSpecificData:developerSpecificDataList){
							if (!StringUtils.isNull(developerSpecificData)&&(!developerSpecificData.equals("null"))){
								Long dataTS = developerSpecificData.getDataTS();
								if (maxdataTS!=null){
									if (dataTS>maxdataTS){
										maxdataTS = dataTS;
										data = developerSpecificData.getData();
									}
								}else {
									maxdataTS = dataTS;
									data = developerSpecificData.getData();
								}
							}
						}
					}
					String dataTs=null;
					if (!StringUtils.isNull(maxdataTS)){
						dataTs = DateUtils.stampToDate(maxdataTS.toString());
					}
					//status获取报警状态
					String status = "";
					int sosAlarm=0;
					int removeAlarm=0;
					int lowVoltageAlarm=0;
					int areaAlarm = 0;//查询告警规则配置
					int heartRateAlarm =0;
					int heartMax=0;
					int heartMin=0;
					AlarmRuleConfig alarmRuleConfig = tagAlarmDataMapper.selectAlarmRuleConfigById(1L);
					if (!StringUtils.isNull(alarmRuleConfig)){
						sosAlarm = alarmRuleConfig.getSosAlarm();
						removeAlarm = alarmRuleConfig.getRemoveAlarm();
						lowVoltageAlarm = alarmRuleConfig.getLowVoltageAlarm();
						areaAlarm = alarmRuleConfig.getAreaAlarm();
						heartRateAlarm = alarmRuleConfig.getHeartRateAlarm();
						heartMax = alarmRuleConfig.getHeartMax();
						heartMin = alarmRuleConfig.getHeartMin();
					}
					if (!StringUtils.isEmpty(data)){
						ArrayList<String> dataList = StringUtils.StringToArrayList(data," ");
						String warnData = dataList.get(2);
						//16转10进制 如OxFF 转化为255
						int warn = DataTypeUtil.hexStringToInt(warnData.substring(2,4));
						//整形转二进制字符串 如:8转为00001000
						String strWarn = DataTypeUtil.binaryAll(warn);
						//判断是否是告警
						if (removeAlarm==1){
							if (strWarn.substring(5,6).equals("1")){
								status+="摘除报警";
							}
						}
						if (sosAlarm==1){
							if (strWarn.substring(6,7).equals("1")){
								if (StringUtils.isEmpty(status)){
									status+="SOS报警";
								}else {
									status+=",SOS报警";
								}
							}
						}
						if (lowVoltageAlarm==1){
							if (strWarn.substring(7,8).equals("1")){
								if (StringUtils.isEmpty(status)){
									status+="低电报警";
								}else {
									status+=",低电报警";
								}
							}
						}

//						tagData.setStatus(status);
						String sensorType = dataList.get(4);//传感器类型
						tagData.setSensorType(sensorType);
						String sensorData = dataList.get(5);//传感值
						//传感值16进制转化为10进制数据
						//16转10进制 如OxFF 转化为255
						int sensorValue = DataTypeUtil.hexStringToInt(sensorData.substring(2,4));
						tagData.setSensorData(sensorValue);
						if (heartRateAlarm==1){
							if (sensorType.equals("0x06")&&(sensorValue!=255)){
								if ((sensorValue>heartMax)||(sensorValue<heartMin)){
									if (StringUtils.isEmpty(status)){
										status+="心率报警";
									}else {
										status+=",心率报警";
									}
								}
							}
						}
						//根据标签ID查找用户ID

					}
//					-- 通过标签ID查询绑定人员的ID和名称、组织
					String deptName = "";
					Long deptId = null;
					String personId = "";
					String personName ="";
					List<Person> personList = tagDataMapper.selectPersonInfoByTagId(tagOneId);
					if (personList.size()>0){
						personId = personList.get(0).getPersonId();
						personName = personList.get(0).getPersonName();
						deptName = personList.get(0).getDeptName();
						deptId = personList.get(0).getDeptId();
						tagOne.setName(personName);
						tagOne.setDept(deptName);
						tagData.setPersonId(personId);
						if (areaAlarm==1){
							//区域报警判断
							Boolean bool = checkAreaAlerm(personList.get(0),tagData);
							if (bool){
								if (StringUtils.isEmpty(status)){
									status+="区域报警";
								}else {
									status+=",区域报警";
								}
							}
						}
					}
					tagData.setStatus(status);
					if (!StringUtils.isEmpty(status)){
						//查询标签报警历史表 未处理的报警状态是否与现在的报警状态一致，如果不一致则存入报警历史表中
						judgeAlarmData(tagData,dataTs);
					}
					//插入数据到标签数据表
//					tagData.setTableName("tag_data_"+tagData.getTagId());
					redisUtil.incr("countTagData",1);
//					tagDataMapper.insertTagData(tagData);
//					获取当前时间，根据当前时间判断应该插入到哪一张表，并且设置partition字段为小时
					String newDate = DateUtils.dateTimeNow();//格式：YYYYMMDDHHMMSS
					//截取年月日,获取表名
					String tableName = "tag_Data_"+newDate.substring(0,8);
					tagData.setTableName(tableName);
					//截取当前小时
					String house = newDate.substring(8,10);
					tagData.setPartition(Integer.parseInt(house));
					insertSqlserverTagData(tagData);
					//更新最新数据到标签最新状态表
					updateTagLatestData(tagData);
					oneList.add(tagOne);//剔除掉不在管理范围的标签数据
				}
			}
		}
		tagPos.setTags(oneList);
		//将过滤后的标签集合通过websocket向前端地图展示人员标签位置
//		MyWebSocket myWebSocket = new MyWebSocket();
//		myWebSocket.onMessage(JSON.toJSONString(tagPos));
	}
	/**
	 * 通过Tdgs中间件接口获取标签数据信息并做相关处理
	 * @return 结果
	 */
	@Override
	public void getTdgsTagData() {
		//获取接口标签数据信息
        String httpAddress = Global.getTdgsIpAndPort();
		String tdgsPosition = HttpUtils.sendPost(" http://"+httpAddress+"/tdgs/getTagPosition","1=1");
		TdgsTagPositiont tagPos = JSON.parseObject(tdgsPosition, TdgsTagPositiont.class);
		List<TdgsTag> oneList = new ArrayList<TdgsTag>();
		List<String> tagIds = selectTagIds();
		if (!StringUtils.isNull(tagPos.getTags())){
			for (TdgsTag tag:tagPos.getTags()){
				processingTagData(tag,tagIds);
			}
		}
//		tagPos.setTags(oneList);
		//将过滤后的标签集合通过websocket向前端地图展示人员标签位置
//		MyWebSocket myWebSocket = new MyWebSocket();
//		myWebSocket.onMessage(JSON.toJSONString(tagPos));
	}
	@Async
	public void  processingTagData(TdgsTag tag,List<String> tagIds){
//		System.out.println("线程" + Thread.currentThread().getName() + " 执行异步任务：" +tag.getID());
		String tagId = tag.getID();
		tagId = tagId.substring(0,10);
		if (tagIds.contains(tagId)){
//				if (checkIsExistTag(tagId)){//校验标签是否存在，不存在的标签数据剔除掉不做处理
			TagData tagData = new TagData();
			//生成ID
			Long id = IdUtil.nextId();
			tagData.setId(id);
			tagData.setTagId(tagId);
			//获取坐标信息时间
			Long positionTS = tag.getPositionTS();
			if (!StringUtils.isNull(positionTS)){
				String positionTime = DateUtils.stampToDate(positionTS.toString());
				tagData.setPositionTS(DateUtils.parseDate(positionTime));
			}
			//获取坐标xyz
			List<BigDecimal> positions =tag.getSmoothedPosition();
			if (!StringUtils.isEmpty(positions)){
				tagData.setX(positions.get(0));
				tagData.setY(positions.get(1));
				tagData.setZ(positions.get(2));
			}else {
				return;
			}
			//获取数据产生时间
			Long lastPacketTS = tag.getLastPacketTS();
			if (!StringUtils.isNull(lastPacketTS)){
				String lastPacketTime = DateUtils.stampToDate(lastPacketTS.toString());
				tagData.setLastPacketTS(DateUtils.parseDate(lastPacketTime));
			}
			//获取电量信息
			BigDecimal batteryVoltage = tag.getVoltage();
			//获取电量信息上报时间
			tagData.setBatteryVoltageTS(tagData.getLastPacketTS());
//					Long batteryVoltageTS = tag.getBatteryVoltageTS();
//					if (!StringUtils.isNull(batteryVoltageTS)){
//						String batteryVoltageTime = DateUtils.stampToDate(batteryVoltageTS.toString());
//						tagData.setBatteryVoltageTS(DateUtils.parseDate(batteryVoltageTime));
//					}
			//获取信号强度
			int rssi = tag.getRssi();
			tagData.setRssi(rssi);
			//获取rssiLocator基站ID
			String rssiLocator = tag.getRssiLocator();
			tagData.setRssiLocator(rssiLocator);

			//status获取报警状态
			String status = "";
			int sosAlarm=0;
			int removeAlarm=0;
			int lowVoltageAlarm=0;
			int areaAlarm = 0;//查询告警规则配置
			int heartRateAlarm =0;
			int heartMax=0;
			int heartMin=0;
			//查询报警规则设置
			AlarmRuleConfig alarmRuleConfig = tagAlarmDataMapper.selectAlarmRuleConfigById(1L);
			if (!StringUtils.isNull(alarmRuleConfig)){
				sosAlarm = alarmRuleConfig.getSosAlarm();
				removeAlarm = alarmRuleConfig.getRemoveAlarm();
				lowVoltageAlarm = alarmRuleConfig.getLowVoltageAlarm();
				areaAlarm = alarmRuleConfig.getAreaAlarm();
				heartRateAlarm = alarmRuleConfig.getHeartRateAlarm();
				heartMax = alarmRuleConfig.getHeartMax();
				heartMin = alarmRuleConfig.getHeartMin();
			}
			if (removeAlarm == 1) {
				String brokenAlarmFlag = tag.getBrokenAlarmFlag();
				if (brokenAlarmFlag.equals("broken")) {
					status += "摘除报警";
				}
			}
			if (sosAlarm == 1) {
				String buttonAlarmFlag = tag.getButtonAlarmFlag();
				if (buttonAlarmFlag.equals("pushed")) {
					if (StringUtils.isEmpty(status)) {
						status += "SOS报警";
					} else {
						status += ",SOS报警";
					}
				}
			}
			if (lowVoltageAlarm == 1) {
				String batteryAlarmFlag = tag.getBatteryAlarmFlag();
				if (batteryAlarmFlag.equals("low")) {
					if (StringUtils.isEmpty(status)) {
						status += "低电报警";
					} else {
						status += ",低电报警";
					}
				}
			}
			int sensorType = tag.getSensorType();//传感器类型
			tagData.setSensorType(""+sensorType);
			int sensorValue = tag.getHeartRate();
			tagData.setSensorData(sensorValue);
			if (heartRateAlarm==1){
				if (sensorType==6&&(sensorValue!=255)){
					if ((sensorValue>heartMax)||(sensorValue<heartMin)){
						if (StringUtils.isEmpty(status)){
							status+="心率报警";
						}else {
							status+=",心率报警";
						}
					}
				}
			}
			//					-- 通过标签ID查询绑定人员的ID和名称、组织
			String deptName = "";
			Long deptId = null;
			String personId = "";
			String personName ="";
			List<Person> personList = tagDataMapper.selectPersonInfoByTagId(tagId);
			if (personList.size()>0){
				personId = personList.get(0).getPersonId();
				personName = personList.get(0).getPersonName();
				deptName = personList.get(0).getDeptName();
				deptId = personList.get(0).getDeptId();
				tag.setName(personName);
				tag.setDept(deptName);
				tagData.setPersonId(personId);
				if (areaAlarm==1){
					//区域报警判断
					Boolean bool = checkAreaAlerm(personList.get(0),tagData);
					if (bool){
						if (StringUtils.isEmpty(status)){
							status+="区域报警";
						}else {
							status+=",区域报警";
						}
					}
				}
			}
			tagData.setStatus(status);
			if (!StringUtils.isEmpty(status)){
				//查询标签报警历史表 未处理的报警状态是否与现在的报警状态一致，如果不一致则存入报警历史表中
				judgeAlarmData(tagData,lastPacketTS.toString());
			}
			//插入数据到标签数据表
//					获取当前时间，根据当前时间判断应该插入到哪一张表，并且设置partition字段为小时
			String newDate = DateUtils.dateTimeNow();//格式：YYYYMMDDHHMMSS
			//截取年月日,获取表名
			String tableName = "tag_Data_"+newDate.substring(0,8);
			tagData.setTableName(tableName);
			//截取当前小时
			String house = newDate.substring(8,10);
			tagData.setPartition(Integer.parseInt(house));
			DynamicDataSourceContextHolder.setDataSourceType(DataSourceType.SLAVE.name());
			tagDataMapper.insertSqlserverTagData(tagData);
			DynamicDataSourceContextHolder.clearDataSourceType();
//					insertSqlserverTagData(tagData);
			//更新最新数据到标签最新状态表
			updateTagLatestData(tagData);
//					oneList.add(tag);//剔除掉不在管理范围的标签数据
		}
	}


//	@DataSource(value = DataSourceType.SLAVE)
	public void insertSqlserverTagData(TagData tagData){
		DynamicDataSourceContextHolder.setDataSourceType(DataSourceType.SLAVE.name());
		tagDataMapper.insertSqlserverTagData(tagData);
		DynamicDataSourceContextHolder.clearDataSourceType();
	}

	/*
	 *查询所有标签ID
	 * @Param tagId
	 */
	public List<String> selectTagIds(){
		return  lableMapper.selectTagIds();
	}

	/*
	*校验标签是否存在
	* @Param tagId
	 */
	public Boolean checkIsExistTag(String tagId){
		Tag tag = lableMapper.selectLableById(tagId);
		if (StringUtils.isNull(tag)){
			return false;
		}
		return true;
	}
	/*
	 *查询标签报警历史表 最新未处理的报警状态是否与现在的报警状态一致，如果不一致则存入报警历史表中
	 * @Param tagId
	 */
	public void judgeAlarmData(TagData tagData,String dataTs){
		String tagId = tagData.getTagId();
		String status = tagData.getStatus();
		TagAlarmData tagAlarmData = new TagAlarmData();
		tagAlarmData.setStatus(0);
		tagAlarmData.setAlarmType(status);
		tagAlarmData.setTagId(tagId);
		List<TagAlarmData> tagAlarmDataList = tagAlarmDataMapper.selectTagAlarmDataList(tagAlarmData);
//		TagAlarmData tagAlarmData = tagAlarmDataMapper.selectLatestTagAlarmData(tagId);
		if (StringUtils.isEmpty(tagAlarmDataList)&&tagAlarmDataList.size()==0){
			//插入报警历史表
			insertTagAlarmData(tagData,dataTs);
		}
//		else{
//			String alarmType = tagAlarmData.getAlarmType();
//			if (!status.equals(alarmType)){
//				insertTagAlarmData(tagData,dataTs);
//			}
//		}
	}
	/*
	 *插入报警历史表
	 * @Param tagId
	 */
	public void insertTagAlarmData(TagData tagData,String dataTs){
		//插入报警历史表
		//生成ID
		Long id = IdUtil.nextId();
		String tagId = tagData.getTagId();
		String status = tagData.getStatus();
		TagAlarmData alarmData = new TagAlarmData();
		alarmData.setId(id);
		alarmData.setAlarmTS(DateUtils.parseDate(dataTs));
		alarmData.setTagId(tagId);
		alarmData.setAlarmType(status);
		alarmData.setX(tagData.getX());
		alarmData.setY(tagData.getY());
		alarmData.setZ(tagData.getZ());
		String personId = tagData.getPersonId();
		//查询人员姓名
		String personName = "";
		if (!StringUtils.isEmpty(personId)){
			Person	person = personMapper.selectPersonById(personId);
			personName=person.getPersonName();
		}
		alarmData.setPersonName(personName);
		//查询未处理报警数量
		Integer num= tagAlarmDataMapper.selectCountTagAlarmDataByStatus(0);
		Integer count = num+1;
		alarmData.setCount(count);
//		try {
//			webSocketServer.sendInfo(JSON.toJSONString(alarmData),"1");
//		} catch (IOException e) {
//			e.printStackTrace();
//		}
		tagAlarmDataMapper.insertTagAlarmData(alarmData);
	}
	/*
	 *更新最新数据到标签最新状态表
	 * @Param tagId
	 */
	public void updateTagLatestData(TagData tagData){
		Tag tagLatestData = new Tag();
		tagLatestData.setTagId(tagData.getTagId());
		tagLatestData.setBatteryVoltage(tagData.getBatteryVoltage());
		tagLatestData.setBatteryVoltageTS(tagData.getBatteryVoltageTS());
		tagLatestData.setLastPacketTS(tagData.getLastPacketTS());
		tagLatestData.setPersonId(tagData.getPersonId());
		tagLatestData.setRssi(tagData.getRssi());
		tagLatestData.setRssiLocator(tagData.getRssiLocator());
		tagLatestData.setSensorData(tagData.getSensorData());
		tagLatestData.setStatus(tagData.getStatus());
		tagLatestData.setX(tagData.getX());
		tagLatestData.setY(tagData.getY());
		tagLatestData.setZ(tagData.getZ());
		tagLatestData.setSensorType(tagData.getSensorType());
		tagLatestData.setPositionTS(tagData.getPositionTS());
		tagLatestData.setIsOnline(1);
		lableMapper.updateLable(tagLatestData);
	}
//	@Override
//	public String getTagPosition() {
//		String httpAddress = Global.getTdmpLeIpAndPort();
//		String tagPosition = HttpUtils.sendPost(" http://"+httpAddress+"/qpe/getTagPosition","version=2");
//		TagPositiont tagPos = JSON.parseObject(tagPosition, TagPositiont.class);
//		List<TagOne> oneList = new ArrayList<TagOne>();
//		if (!StringUtils.isNull(tagPos.getTags())){
//			for (TagOne tagOne:tagPos.getTags()){
//				String tagOneId = tagOne.getId();
//				if (checkIsExistTag(tagOneId)){//校验标签是否存在，不存在的标签数据剔除掉不做处理
//					//-- 通过标签ID查询绑定人员的ID和名称、组织
//					String deptName = "";
//					String personName ="";
//					String status = null;
//					List<Person> personList = tagDataMapper.selectPersonInfoByTagId(tagOneId);
//					if (personList.size()>0){
//						personName = personList.get(0).getPersonName();
//						deptName = personList.get(0).getDeptName();
//						tagOne.setName(personName);
//						tagOne.setDept(deptName);
//					}
//					//查询标签是否未处理报警
//					TagAlarmData tagAlarmData = new TagAlarmData();
//					tagAlarmData.setTagId(tagOneId);
//					tagAlarmData.setStatus(0);//未处理
//					List<TagAlarmData> tagAlarmDataList = tagAlarmDataMapper.selectTagAlarmDataList(tagAlarmData);
//					if (StringUtils.isNotEmpty(tagAlarmDataList)&&tagAlarmDataList.size()>0){
//						tagOne.setStatus("1");
//					}
//					oneList.add(tagOne);//剔除掉不在管理范围的标签数据
//				}
//			}
//		}
//		tagPos.setTags(oneList);
//		return JSON.toJSONString(tagPos);
//	}
	/*
	 *校验区域是否报警
	 * @Param tagId
	 */
	public Boolean checkAreaAlerm(Person person,TagData tagData){
		Boolean result = false;//返回结果
		String personId = person.getPersonId();
		Long deptId = person.getDeptId();
		BigDecimal x =tagData.getX();
		BigDecimal y = tagData.getY();
		//查询区域信息
		List<Area> areaList = areaMapper.selectAreaByDeptIdAndPersonID(person);
		if (areaList.size()>0){
			for (Area a : areaList){
				String rule = a.getRule();//规则
				Integer ruleTime = a.getRuleTime();//持续时间
				//判断点是否在区域内 true为在区域内，false不在区域内
				Boolean bool= CheckIsInPolygon.isInPolygon(Double.parseDouble(x.toString()),Double.parseDouble(y.toString()),a.getPointData());
				//1禁入,2禁出,3巡检
				if (rule.equals("1")){//如果禁入
					if (bool){//true为在区域内，计入报警持续时间
						//redis记录报警持续时间，每次自增+1，如果不在区域内这数据清空
						redisUtil.incr(personId+"Area"+a.getAreaId(),1);
						String longtime = redisUtil.get(personId+"Area"+a.getAreaId()).toString();
						//判断longtime是否大于等于规则持续时间
						if (Integer.valueOf(longtime)>=ruleTime){
							//产生报警,返回结果true
							result=true;
						}
					}else {
						//不在区域内，则清空longtime
						redisUtil.del(personId+"Area"+a.getAreaId());
					}
				}else if (rule.equals("2")){//如果禁出
					if (!bool){//true为不在区域内，计入报警持续时间
						//redis记录报警持续时间，每次自增+1，如果不在区域内这数据清空
						redisUtil.incr(personId+"Area"+a.getAreaId(),1);
						String longtime = redisUtil.get(personId+"Area"+a.getAreaId()).toString();
						//判断longtime是否大于等于规则持续时间
						if (Integer.valueOf(longtime)>=ruleTime){
							//产生报警,返回结果true
							result=true;
						}
					}else {
						//不在区域内，则清空longtime
						redisUtil.del(personId+"Area"+a.getAreaId());
					}
				}else if (rule.equals("3")){//如果巡检
					//巡检暂不考虑
				}
			}
		}
		return result;
	}

	@Override
	public String getTagPosition() {
		//获取接口标签数据信息
		long bt = System.currentTimeMillis();
		String httpAddress = Global.getTdgsIpAndPort();
		String tdgsPosition = "";
		try {
			tdgsPosition = HttpUtils.sendPost(" http://"+httpAddress+"/tdgs/getTagPosition","1=1");
		}catch (Exception e){
			System.out.println(e.getMessage());
		}
		TagPositiont tagPositiont = new TagPositiont();
		tagPositiont.setResponseTS(new Date().getTime());
		tagPositiont.setVersion("2.1");
		List<TagOne> listTagOne = new ArrayList<TagOne>();
		if (!StringUtils.isEmpty(tdgsPosition)){
			TdgsTagPositiont tagPos = JSON.parseObject(tdgsPosition, TdgsTagPositiont.class);
			List<TdgsTag> tdgsTagList= tagPos.getTags();
			List<TdgsTag> oneList = new ArrayList<TdgsTag>();
			//查询所有标签ID
			List<String> tagIds = selectTagIds();
			//查询所有报警未处理的标签ID集合
			List<String> tagIdList = tagAlarmDataMapper.selectTagIdsIsAlarm();
			//查询所有离线标签
			Tag offlineTag = new Tag();
			offlineTag.setIsOnline(0);
			List<Tag> offlineTagList = lableMapper.selectLableList(offlineTag);
			if (!StringUtils.isEmpty(offlineTagList)){
				for (Tag t:offlineTagList){
					TdgsTag tdgsTag = new TdgsTag();
					tdgsTag.setID(t.getTagId());
					BigDecimal x = t.getX();
					BigDecimal y = t.getY();
					BigDecimal z = t.getZ();
					List<BigDecimal> position = new ArrayList<BigDecimal>();
					position.add(x);
					position.add(y);
					position.add(z);
					tdgsTag.setSmoothedPosition(position);
					tdgsTag.setStatus("0");//代表离线
					tdgsTagList.add(tdgsTag);
				}
			}
			if (!StringUtils.isNull(tdgsTagList)) {
				List<Future<TagOne>> futureList = new ArrayList<Future<TagOne>>();
				for (TdgsTag tag : tdgsTagList) {
					// 创建具有返回值的线程任务
					MyCallable myCallable = new MyCallable(tag,tagIdList,tagIds);
					// 执行任务并获取Future对象
					Future future = threadPool.submit(myCallable);
					futureList.add(future);
//					String tagId = tag.getID();
//					tagId = tagId.substring(0,10);
//					String status = tag.getStatus();
//					if (!StringUtils.isEmpty(status)){
//
//					}
//					//校验标签是否存在，不存在的标签数据剔除掉不做处理
//					if (tagIds.contains(tagId)) {
//						//获取坐标xyz
//						List<BigDecimal> positions = tag.getSmoothedPosition();
//						// 创建具有返回值的线程任务
//						MyCallable myCallable = new MyCallable(tag,tagIdList,tagIds);
//						// 执行任务并获取Future对象
//						Future future = threadPool.submit(myCallable);
//						try {
//							listTagOne.add((TagOne) future.get());
//						} catch (InterruptedException e) {
//							e.printStackTrace();
//						} catch (ExecutionException e) {
//							e.printStackTrace();
//						}
//					}
				}
				if (!StringUtils.isEmpty(futureList)){
					for(Future<TagOne> f : futureList){
						try {
							if (StringUtils.isNotNull(f.get())){
								listTagOne.add(f.get());
							}
//							System.out.println(f.get());
						} catch (InterruptedException e) {
							e.printStackTrace();
						} catch (ExecutionException e) {
							e.printStackTrace();
						}
					}
				}
			}
		}
		tagPositiont.setTags(listTagOne);
		long et2 = System.currentTimeMillis();
//		System.out.println("[1]耗时:"+(et2 - bt)+ "ms");
		return JSON.toJSONString(tagPositiont);
    }
    //通过坐标转换成tdmp格式
//    public TagOne tdgsTransformTdmp(List<BigDecimal> position,String tagId,List<String> tagIdList){
//        TagPositiont tagPositiont = new TagPositiont();
//        TagOne tagOne = new TagOne();
//        String coordinateSystemId = Global.getCoordinateSystemId();
//        tagOne.setCoordinateSystemId(coordinateSystemId);
//        tagOne.setId(tagId);
//        tagOne.setPositionTS(new Date().getTime());
//        tagOne.setSmoothedPosition(position);
//        tagOne.setZones(new ArrayList<Zone>());
//		//-- 通过标签ID查询绑定人员的ID和名称、组织
//		String deptName = null;
//		String personName =null;
//		List<Person> personList = tagDataMapper.selectPersonInfoByTagId(tagId);
//		if (personList.size()>0) {
//			personName = personList.get(0).getPersonName();
//			deptName = personList.get(0).getDeptName();
//		}
//		tagOne.setName(personName);
//		tagOne.setDept(deptName);
//		if (tagIdList.contains(tagId)) {
//			tagOne.setStatus("1");
//		}else {
//			tagOne.setStatus("0");
//		}
//		return tagOne;
//    }
	//通过坐标转换成tdmp格式
	public TagOne tdgsTransformTdmp(TdgsTag tag,List<String> tagIdList,List<String> tagIds){
		String tagId = tag.getID();
		tagId = tagId.substring(0,10);
		String status = tag.getStatus();
		//校验标签是否存在，不存在的标签数据剔除掉不做处理
		if (tagIds.contains(tagId)) {
			//获取坐标xyz
			List<BigDecimal> position = tag.getSmoothedPosition();
//			TagPositiont tagPositiont = new TagPositiont();
			TagOne tagOne = new TagOne();
			String coordinateSystemId = Global.getCoordinateSystemId();
			tagOne.setCoordinateSystemId(coordinateSystemId);
			tagOne.setId(tagId);
			tagOne.setPositionTS(new Date().getTime());
			tagOne.setSmoothedPosition(position);
			tagOne.setZones(new ArrayList<Zone>());
			//-- 通过标签ID查询绑定人员的ID和名称、组织
			String deptName = null;
			String personName =null;
			List<Person> personList = tagDataMapper.selectPersonInfoByTagId(tagId);
			if (personList.size()>0) {
				personName = personList.get(0).getPersonName();
				deptName = personList.get(0).getDeptName();
			}
			tagOne.setName(personName);
			tagOne.setDept(deptName);
			if (!StringUtils.isEmpty(status)){
				if (status.equals("0")){
					tagOne.setStatus("0");//离线
				}
			}if (tagIdList.contains(tagId)) {
				tagOne.setStatus("1");//报警
			}
			return tagOne;

		}
		return null;
	}
	/**
	 * 任务1->创建数据库(多线程返回值)
	 * @author XXX
	 * @date 2019/5/31 16:40
	 * @version 1.0
	 */
	class MyCallable implements Callable {
		private TdgsTag tag;
		private List<String> tagIds;
		private List<String> tagIdList;
		public MyCallable(TdgsTag tag,List<String> tagIdList,List<String> tagIds) {
			this.tag = tag;
			this.tagIdList = tagIdList;
			this.tagIds = tagIds;
		}
		@Override
		public TagOne call() throws Exception {
			return synchrCreateDb(tag,tagIdList,tagIds);
		}
	}
	/**
	 * 同步方法创建库
	 * @author XXX
	 * @date 2019/6/13 16:24
	 * @version 1.0
	 */
	public TagOne synchrCreateDb(TdgsTag tag,List<String> tagIdList,List<String> tagIds) {
		return tdgsTransformTdmp(tag,tagIdList,tagIds);
	}
	public TagOne createDb(TdgsTag tag,List<String> tagIdList,List<String> tagIds) {
		// 创建具有返回值的线程任务
		MyCallable myCallable = new MyCallable(tag,tagIdList,tagIds);
		// 执行任务并获取Future对象
		Future future = threadPool.submit(myCallable);
//		System.out.println("多线程异步执行"+Thread.currentThread().getName());
		try {
			// 从Future对象上获取任务的返回值,并返回
			return (TagOne) future.get();
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}
}
